var MAP_TILE_SIZE = 60;
var MAP_SIZE_W = 21;
var MAP_SIZE_H = 12;
var MAP_TILE_WATER = 0;
var MAP_TILE_SNOW  = 1;


var NUMBER_OF_BOMB = 10;
var NUMBER_OF_EXPLOSION = 30;


var BATTLE_OFFSET_X = 10;
var BATTLE_OFFSET_Y = 0;

var DEFINE_ENTITY_RESOURCE_FROM = 21;
var DEFINE_ENTITY_RESOURCE_TO = 22;
var GROUND_EMPTY = 0;
var GROUND_WATER = 1;
var GROUND_ENTITY = 2;
var GROUND_RESOURCE = 9;

function Battle () {
	var battle = this;
	// Battle status
	this.m_isMultiPlayer = false;
	
	// Battle object
	this.m_map = new Map();
	this.m_entity = new Array();
	this.m_penguin = new Array();
	this.m_enemy = new Array();
	this.m_bomb = new Array();
	this.m_explosion = new Array();
	this.m_playerIndex = 0;
	
	
	for (var i=0; i<NUMBER_OF_BOMB; i++) {
		this.m_bomb[i] = new Bomb(this);
	}
	for (var i=0; i<NUMBER_OF_EXPLOSION; i++) {
		this.m_explosion[i] = new Explosion(this);
	}
	
	
	// For main player only
	var THROW_FORCE_MAX = 1;
	var THROW_FORCE_MULTIPLIER = 0.002;
	var throwing = 0;
	var throwForce = 0;
	var mustStopThrowFlag = 0;
	
	
	var drawObject = null;
	this.pathMap = null;
	
	this.LoadMap = function (groundMap, entityMap, reverse) {
		this.m_map.LoadMapFromArray (groundMap, reverse);
		this.m_map.Render();
		
		for (var i=0; i<MAP_SIZE_W; i++) {
			for (var j=0; j<MAP_SIZE_H; j++) {
				if (entityMap[j][i] > 0) {
					if (reverse) this.m_entity[this.m_entity.length] = new Entity (this, entityMap[j][i], i, j);
					else         this.m_entity[this.m_entity.length] = new Entity (this, entityMap[i][j], i, j);
				}
			}
		}
		
		this.pathMap = new Array();
		for (var i=0; i<MAP_SIZE_W+1; i++) {
			this.pathMap[i] = new Array();
			for (var j=0; j<MAP_SIZE_H+1; j++) {
				if (i==MAP_SIZE_W || j==MAP_SIZE_H) {
					 this.pathMap[i][j] = 0;
					 continue;
				}
				
				var a, b;
				if (reverse) {a = j; b = i;}
				else         {a = i; b = j;}
				
				if (groundMap[a][b] == 0) this.pathMap[i][j] = GROUND_WATER;
				else {
					if (entityMap [a][b] >= DEFINE_ENTITY_RESOURCE_FROM && entityMap [a][b] <= DEFINE_ENTITY_RESOURCE_TO)
						this.pathMap[i][j] = GROUND_RESOURCE;
					else if (entityMap [a][b] > 0)
						this.pathMap[i][j] = GROUND_ENTITY;
					else
						this.pathMap[i][j] = GROUND_EMPTY;
				}
			}
		}
		
		drawObject = new Array();
		for (var i=0; i<this.m_entity.length; i++) {
			drawObject[drawObject.length] = this.m_entity[i];
			this.m_entity[i].Init();
		}
		for (var i=0; i<this.m_penguin.length; i++) {
			drawObject[drawObject.length] = this.m_penguin[i];
			this.m_penguin[i].Init();
		}
		for (var i=0; i<this.m_enemy.length; i++) {
			drawObject[drawObject.length] = this.m_enemy[i];
			this.m_enemy[i].Init();
		}
	}
	
	
	
	
	
	
	
	
	
	
	
	// FOR TESTING PURPOSE ============================================
	this.m_penguin[this.m_playerIndex] = new Penguin (this);
	this.m_penguin[this.m_playerIndex].m_x = 0;
	this.m_penguin[this.m_playerIndex].m_y = 0;
	
	this.m_enemy[0] = new Harvester (this);
	this.m_enemy[0].m_x = 600;
	this.m_enemy[0].m_y = 600;
	
	var groundMap = [
		[01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 00, 00, 00],
		[01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 00, 00, 00, 00],
		[01, 01, 01, 01, 01, 01, 00, 00, 00, 00, 00, 01, 01, 01, 01, 00, 00, 00, 00, 00, 00],
		[01, 01, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 01, 00, 00, 00, 00, 00, 00, 00],
		[01, 01, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00],
		[01, 01, 01, 00, 00, 00, 01, 01, 01, 01, 01, 00, 00, 00, 00, 01, 01, 01, 01, 01, 01],
		[01, 01, 01, 00, 00, 00, 01, 01, 01, 01, 01, 01, 00, 00, 01, 01, 01, 01, 01, 01, 01],
		[01, 01, 01, 00, 00, 00, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01],
		[01, 01, 00, 00, 00, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01],
		[01, 00, 00, 00, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01],
		[00, 00, 00, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01],
		[00, 00, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01]
	];
	
	var entityMap = [
		[00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00],
		[00, 00, 00, 00, 00, 21, 00, 00, 00, 00, 00, 22, 02, 02, 00, 00, 00, 00, 00, 00, 00],
		[00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00],
		[00, 02, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00],
		[00, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00],
		[00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00],
		[00, 00, 00, 00, 00, 00, 00, 21, 00, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00],
		[02, 00, 00, 00, 00, 00, 00, 00, 00, 02, 00, 00, 00, 00, 00, 00, 00, 02, 02, 01, 00],
		[00, 00, 00, 00, 00, 00, 00, 01, 01, 02, 00, 22, 00, 00, 00, 00, 00, 01, 00, 00, 00],
		[00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00, 00, 22, 00, 00, 01, 00, 21, 00],
		[00, 00, 00, 00, 00, 02, 02, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00],
		[00, 00, 00, 00, 00, 02, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00]
	];
	
	setTimeout (function () {
		battle.LoadMap (groundMap, entityMap, true);
	}, 100);
	// =================================================================
	
	
	
	
	
	this.Update = function () {
		if (throwing == true) {
			throwForce += g_deltaTime * THROW_FORCE_MULTIPLIER;
			if (throwForce > THROW_FORCE_MAX) {
				throwForce = THROW_FORCE_MAX;
				throwing = false;
				this.m_penguin[this.m_playerIndex].Order(3, null, throwForce);
				mustStopThrowFlag = 1;
				throwForce = 0;
			}
		}
		
		this.m_map.Update();
		
		for (var i=0; i<this.m_penguin.length; i++) {
			this.m_penguin[i].Update();
		}
		for (var i=0; i<this.m_enemy.length; i++) {
			this.m_enemy[i].Update();
		}
		
		for (var i=0; i<NUMBER_OF_BOMB; i++) {
			this.m_bomb[i].Update();
		}
		for (var i=0; i<NUMBER_OF_EXPLOSION; i++) {
			this.m_explosion[i].Update();
		}
	}
	
	this.Draw = function () {
		this.m_map.Draw();
		
		drawObject.sort (function (a, b) {
			if (a.m_y == b.m_y) {
				return a.m_x - b.m_x;
			}
			return a.m_y - b.m_y;
		});
		for (var i=0; i<drawObject.length; i++) {
			drawObject[i].Draw();
		}
		
		for (var i=0; i<NUMBER_OF_BOMB; i++) {
			this.m_bomb[i].Draw();
		}
		for (var i=0; i<NUMBER_OF_EXPLOSION; i++) {
			this.m_explosion[i].Draw();
		}
	}
	
	
	this.ThrowBomb = function (x, y, direction, force) {
		for (var i=0; i<NUMBER_OF_BOMB; i++) {
			if (this.m_bomb[i].m_active == false) {
				this.m_bomb[i].Start (x, y, direction, force);
				return;
			}
		}
	}
	
	this.StartExplosion = function (type, x, y) {
		for (var i=0; i<NUMBER_OF_EXPLOSION; i++) {
			if (this.m_explosion[i].m_active == false) {
				this.m_explosion[i].SetType (type);
				this.m_explosion[i].Start (x, y);
				return;
			}
		}
	}
	
	
	
	
	
	
	
	
	
	this.OnKeyDown = function (keycode) {
		if (keycode >= 37 && keycode <= 40) {
			var allowMove = 1;
			if (throwing == false) allowMove = 1;
			else                   allowMove = 0;
			
			if (keycode == 37) 	    this.m_penguin[this.m_playerIndex].Order(allowMove, 1);
			else if (keycode == 38) this.m_penguin[this.m_playerIndex].Order(allowMove, 2);
			else if (keycode == 39) this.m_penguin[this.m_playerIndex].Order(allowMove, 3);
			else if (keycode == 40) this.m_penguin[this.m_playerIndex].Order(allowMove, 0);
		}
		else if (keycode == 32)      {
			if (mustStopThrowFlag == 0 && throwing == false) {
				this.m_penguin[this.m_playerIndex].Order(2, null);
				throwing = true;
				throwForce = 0;
			}
		}
	}
	
	this.OnKeyUp = function (keycode) {
		if (keycode >= 37 && keycode <= 40) {
			this.m_penguin[this.m_playerIndex].Order(0, null);
		}
		else if (keycode == 32)      {
			if (throwing == true) {
				this.m_penguin[this.m_playerIndex].Order(3, null, throwForce);
				throwing = false;
				throwForce = 0;
			}
			mustStopThrowFlag = 0;
		}
	}
	
	
	this.GetMyPenguinHPPercentage = function () {
		// temporary:
		return 0.8;
	}
	
	this.GetMyPenguinEnergyPercentage = function () {
		// temporary:
		return 0.4;
	}
	
	
	
	
	this.GetThrowForcePercentage = function() {
		return throwForce / THROW_FORCE_MAX;
	}
}